<?php


namespace PKApp\Content;

use PKApp\Content\Classes\TraitContent;
use PKApp\Model\Classes\TraitModel;
use PKCommon\Controller\AdminController;
use PKFrame\DataHandler\Arrays;
use PKFrame\DataHandler\Numbers;

class AdminSetCategory extends AdminController
{
    use TraitContent, TraitModel;

    private $_entityList;
    protected $service_category;

    public function __construct()
    {
        parent::__construct();
        $this->service_category = $this->serviceOfCategory($this->loginUser()->SiteId);
    }

    public function Main()
    {
        $params = ['id' => Numbers::To(request()->get('id')),];
        if (request()->has('categoryType', 'get')) {
            $type = request()->get('categoryType');
            $params['categoryType'] = $type;
        } else {
            $id_parent = request()->get('parentId');
            $entity = $this->service_category->interface_getEntityById($id_parent);
            $type = $entity['categoryType'];
            $params = array_merge($params, ['id' => 0, 'parentId' => $id_parent]);
        }
        $this->assign($params)->fetch('category_form_' . $type);
    }

    private function _typeBYLink($post)
    {
        $this->_postHandler($post);
    }

    private function _typeBYPage($post)
    {
        if (in_array('changeCategoryTplPower', $this->loginUser()->PowerByAction)
            && array_key_exists('template', $post) && is_array($post['template'])) {
            $post['template'] = serialize($post['template']);
        }
        $this->_postHandler($post);
    }

    private function _typeBYList($post)
    {
        $post['modelId'] = Numbers::To(request()->post('modelId'));
        $this->serviceOfModel()->isContentOfModel($post['modelId']);
        // 检查单页面的SEO编辑权限
        if (array_key_exists('seo', $post) && is_array($post['seo'])) {
            !empty($post['seo']['title']) ?: $post['seo']['title'] = $post['name'];
            !empty($post['seo']['keyword']) ?: $post['seo']['keyword'] = $post['name'];
            !empty($post['seo']['description']) ?: $post['seo']['description'] = $post['name'];
            $post['seo'] = serialize($post['seo']);
        }
        if (array_key_exists('template', $post) && is_array($post['template'])) {
            $post['template'] = serialize($post['template']);
        }
        if (array_key_exists('inherit', $post)) {
            unset($post['inherit']);
        }
        if (Numbers::IsId($post['parentId'])) {
            $entity_parent = array_filter($this->_entityList, function ($entity) use ($post) {
                return $entity['id'] == $post['parentId'] ? $entity : [];
            });
            !Arrays::Is($entity_parent) ?: $entity_parent = end($entity_parent);
            if (Arrays::Is($entity_parent) && $entity_parent['categoryType'] == 'list') {
                $entity_parent['modelId'] == $post['modelId'] ?: $this->noticeByJson('category_PCModel_Error');
            }
        }
        $this->_postHandler($post);
    }

    private function _postHandler($post)
    {
        $fromParentId = $post['fromParentId'];
        unset($post['fromParentId']);
        if (Numbers::IsId($post['parentId'])) {
            $parentIdList = $this->_treeParent($post['parentId']);
            $post['parentIdList'] = Arrays::Is($parentIdList) ? implode(',', array_unique($parentIdList)) : '';
        } else {
            $post['parentIdList'] = null;
        }
        switch (request()->action()) {
            case 'ApiByCreate':
                $post['id'] = $this->service_category->Add($post);
                if ($post['categoryType'] == 'page') {
                    $this->serviceOfPage()->Add(['id' => $post['id'], 'title' => $post['name'],
                        'siteId' => $this->loginUser()->SiteId]);
                }
                break;
            case 'ApiByChange':
                $this->service_category->UpdateById($post['id'], $post);
                break;
        }
        // 将新修改的栏目信息追加到现在的列表中
        $this->_entityList[] = $post;
        // 父级栏目更新其下的子栏目
        $nowArrChildId = $this->_treeChild($post['id']);
        $this->service_category->UpdateById($post['id'],
            ['childrenIdList' => Arrays::Is($nowArrChildId) ? implode(',', array_unique($nowArrChildId)) : '']);
        if (!empty($post['parentId'])) {
            // 父级栏目更新其下的子栏目
            $parentArrChildId = $this->_treeChild($post['parentId']);
            $this->service_category->UpdateById($post['parentId'],
                ['childrenIdList' => Arrays::Is($parentArrChildId) ? implode(',', array_unique($parentArrChildId)) : '']);
            // 父级栏目的上上级栏目
            $parentArrParent = $this->_treeParent($post['parentId']);
            if (count($parentArrParent) > 0) {
                foreach ($parentArrParent as $item) {
                    if ($item != $post['parentId']) {
                        $parentArrChildId = $this->_treeChild($item);
                        $this->service_category->UpdateById($item,
                            ['childrenIdList' => Arrays::Is($parentArrChildId) ? implode(',', array_unique($parentArrChildId)) : '']
                        );
                    }
                }
            }
        }
        if (request()->action() == 'ApiByChange' && $fromParentId != $post['parentId']) {
            // 原来父级栏目更新其下的子栏目
            if (Numbers::IsId($fromParentId)) {
                $fromParentArrChildId = $this->_treeChild($fromParentId);
                $this->service_category->UpdateById($fromParentId,
                    ['childrenIdList' => Arrays::Is($fromParentArrChildId) ? implode(',', array_unique($fromParentArrChildId)) : '']);
            }
            // 原来父级栏目的上上级栏目
            $parentArrParent = $this->_treeParent($fromParentId);
            if (count($parentArrParent) > 0) {
                foreach ($parentArrParent as $item) {
                    if ($item != $fromParentId) {
                        $parentArrChildId = $this->_treeChild($item);
                        $this->service_category->UpdateById($item,
                            ['childrenIdList' => Arrays::Is($parentArrChildId) ? implode(',', array_unique($parentArrChildId)) : '']
                        );
                    }
                }
            }
        }
        $this->inputSuccess();
    }

    private function _treeParent($id): array
    {
        $result = [];
        if ($id == 0) {
            return $result;
        }
        $nowChild = array_filter($this->_entityList, function ($entity) use ($id) {
            return $entity['id'] == $id ? $entity : [];
        });
        if (Arrays::Is($nowChild)) {
            foreach ($nowChild as $item) {
                $tmp = $this->_treeParent($item['parentId']);
                $result[] = $item['id'];
                !Arrays::Is($tmp) ?: $result = array_merge($result, $tmp);
            }
        }
        return $result;
    }

    private function _treeChild($parentId): array
    {
        $result = [];
        $nowChild = array_filter($this->_entityList, function ($entity) use ($parentId) {
            return $entity['parentId'] == $parentId ? $entity : [];
        });
        if (Arrays::Is($nowChild)) {
            foreach ($nowChild as $item) {
                $tmp = $this->_treeChild($item['id']);
                !Arrays::Is($tmp) ?: $result = array_merge($result, $tmp);
                $result[] = $item['id'];
            }
        }
        return $result;
    }

    protected function model(): array
    {
        in_array('changeCategoryBaseSetPower', $this->loginUser()->PowerByAction) ?: $this->noticeByJson('Category_PowerError');
        $post = $this->checkModel(array(
            'name', 'fromParentId', 'parentId', 'info', 'categoryType',
            'image', 'url', 'isShow'
        ));
        $post['name'] = $this->checkPostFieldIsEmpty('name', 'Category_NameEmpty');
        $post['fromParentId'] = Numbers::To($post['fromParentId']);
        $post['parentId'] = Numbers::To($post['parentId']);
        array_key_exists('isShow', $post) ?: $post['isShow'] = 0;
        $post['isDeleted'] = 0;
        if (in_array($post['categoryType'], ['page', 'list'])) {
            if ($post['categoryType'] == 'list') {
                if (in_array('changeCategorySEOPower', $this->loginUser()->PowerByAction)) {
                    $seo = request()->post('seo');
                    Arrays::Is($seo) ?: $this->noticeByJson('Category_seo_Empty');
                    $post = array_merge($post, [
                        'seo' => $this->checkModel(['title', 'keyword', 'description'], $seo)
                    ]);
                }
                // 判断是否分配了扩展信息的修改权限
                if (in_array('changeCategoryHeightSetPower', $this->loginUser()->PowerByAction)) {
                    $power = request()->post('power');
                    Arrays::Is($power) ?: $this->noticeByJson('Category_power_Empty');
                    $post = array_merge($post, [
                        'power' => $this->checkModel(['EditGroup', 'ReadMeGroup'], $power)
                    ]);
                    $post['power'] = serialize($post['power']);
                }
                $list_template = dict('tplConfig_ofList');
            } else {
                $list_template = dict('tplConfig_ofPage');
            }
            if (in_array('changeCategoryTplPower', $this->loginUser()->PowerByAction)) {
                $template = request()->post('template');
                Arrays::Is($template) ?: $this->noticeByJson('Category_tplEmpty');
                $post = array_merge($post, [
                    'template' => $this->checkModel($list_template, $template)
                ]);
            }
        }
        $post['siteId'] = $this->loginUser()->SiteId;
        $this->_entityList = $this->service_category->GetList();
        return $post;
    }

    public function ApiByCreate()
    {
        $post = $this->model();
        switch ($post['categoryType']) {
            case 'link':
                $this->_typeBYLink($post);
                break;
            case 'page':
                $this->_typeBYPage($post);
                break;
            case 'list':
                $this->_typeBYList($post);
                break;
        }
    }

    public function ApiByChange()
    {
        $post = $this->model();
        $post['id'] = $id = $this->postId('id', 'Category_idEmpty');
        $arrChildId = $this->_treeChild($id);
        $post['childrenIdList'] = Arrays::Is($arrChildId) ? implode(',', $arrChildId) : '';
        switch ($post['categoryType']) {
            case 'link':
                $this->_typeBYLink($post);
                break;
            case 'page':
                $this->_typeBYPage($post);
                break;
            case 'list':
                $this->_typeBYList($post);
                break;
        }
    }

    public function ApiByDel()
    {
        $ids = request()->post('id');
        Arrays::Is($ids) ?: $ids = [$ids];
        $new_id = [];
        foreach ($ids as $id) {
            !is_numeric($id) ?: $new_id[] = $id;
        }
        $lists = $this->service_category->GetListByParent($new_id, ['id']);
        if (Arrays::Is($lists)) {
            $lists = Arrays::Column($lists, 'id');
            foreach ($lists as $id) {
                in_array($id, $new_id) ?: $this->noticeByJson('Category_BatchDelError');
            }
        }
        $this->service_category->HideById($new_id);
        $this->inputSuccess();
    }

    public function ApiByTplConfig()
    {
        $id = $this->getId('id', 'Category_idEmpty');
        $entity = $this->service_category->interface_getEntityById($id);
        $childrenIdList = [];
        if (!empty($entity['childrenIdList'])) {
            $childrenIdList_tmp = explode(',', $entity['childrenIdList']);
            foreach ($childrenIdList_tmp as $item_id) {
                !Numbers::Is($item_id) ?: array_push($childrenIdList, $item_id);
            }
        }
        if (Arrays::Is($childrenIdList) && array_key_exists('template', $entity) && !empty($entity['template'])) {
            $this->service_category->Update(['id' => $childrenIdList], ['template' => serialize($entity['template'])]);
        }
        $this->inputSuccess();
    }

    public function ApiBySortIndex()
    {
        $this->service_category->UpdateById(
            request()->post('id'),
            ['listSort' => Numbers::To(request()->post('sortIndex'))]
        );
        $this->inputSuccess();
    }

    /**
     * 整理栏目的上下文
     */
    public function ApiByContext()
    {
        $id = $this->getId('id', 'Category_idEmpty');
        $entity_now = $this->service_category->interface_getEntityById($id);
        $this->_entityList = $this->service_category->GetList();
        $up_data = [];
        if (Numbers::IsId($entity_now['parentId'])) {
            $parentIdList = $this->_treeParent($entity_now['parentId']);
            $up_data['parentIdList'] = Arrays::Is($parentIdList) ? implode(',', array_unique($parentIdList)) : '';
        } else {
            $up_data['parentIdList'] = null;
        }
        $nowArrChildId = $this->_treeChild($entity_now['id']);
        $up_data = array_merge($up_data,
            ['childrenIdList' => Arrays::Is($nowArrChildId) ? implode(',', array_unique($nowArrChildId)) : '']);
        $this->service_category->UpdateById($entity_now['id'], $up_data);
        $this->json();
    }

}
